EnableExplicit

;{- Calculate Minimum Gadget Size

;  Calculates the size required to display a Gadget properly.
;
;  Supported Gadgets:
;    Button, Checkbox, Option, Text, String, ComboBox, Image
;
;  Note:
;    For Gadgets with variable content (String, ComboBox), only the returned height
;    is useful, as the width will only be an absolute minimum value.
;
;  The 'Flags' parameter gives gadget flags to include in the calculation.
;  Currently only #PB_Text_Border makes a difference there.   
;

CompilerIf Defined(Max, #PB_Procedure) = 0
  Procedure Max(a, b)
    If a > b
      ProcedureReturn a
    Else
      ProcedureReturn b
    EndIf
  EndProcedure
CompilerEndIf

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  Structure PB_Gadget
    *Gadget.GtkWidget
    *Container.GtkWidget
    *VT
    UserData.i
    GadgetData.i[4]
  EndStructure
CompilerEndIf

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  Structure OSX_Rect
    top.w
    left.w
    bottom.w
    right.w
  EndStructure
 
  #noErr = 0
CompilerEndIf


; Stores the result in *Width\w and *Height\w
;
Procedure GetRequiredSize(Gadget, *Width.Word, *Height.Word, Flags = 0)

  CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
 
    Protected DC.i = GetDC_(GadgetID(Gadget))
    Protected oldFont = SelectObject_(DC, GetGadgetFont(Gadget))
    Protected Size.Size
 
    Select GadgetType(Gadget)
   
      Case #PB_GadgetType_Text
        Protected Text$ = RemoveString(GetGadgetText(Gadget), Chr(10))
        Protected count = CountString(Text$, Chr(13)) + 1
        Protected empty = 0
        Protected maxheight = 0
        Protected index
        For index = 1 To count
          Protected Line$ = StringField(Text$, index, Chr(13))
          If Line$ = ""
            empty + 1
          Else
            Protected LineSize.Size
            GetTextExtentPoint32_(DC, @Line$, Len(Line$), @LineSize)
            Size\cx = Max(Size\cx, LineSize\cx)
            Size\cy + LineSize\cy
            maxheight = Max(maxheight, LineSize\cy)
          EndIf
        Next index           
        Size\cy + empty * maxheight 
       
        If Flags & #PB_Text_Border
          Size\cx + GetSystemMetrics_(#SM_CXEDGE) * 2
          Size\cy + GetSystemMetrics_(#SM_CYEDGE) * 2
        Else           
          Size\cx + 2
          Size\cy + 2
        EndIf

      Case #PB_GadgetType_CheckBox, #PB_GadgetType_Option
        Text$ = GetGadgetText(Gadget)
        GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
        Size\cx + 20
        Size\cy = Max(Size\cy+2, 20)
       
      Case #PB_GadgetType_Button
        Text$ = GetGadgetText(Gadget)
        GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
        Size\cx + GetSystemMetrics_(#SM_CXEDGE)*2
        Size\cy = Max(Size\cy+GetSystemMetrics_(#SM_CYEDGE)*2, 24)
        Size\cx + 10
       
      Case #PB_GadgetType_String
        Text$ = GetGadgetText(Gadget) + "Hg"
        GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
        Size\cx = GetSystemMetrics_(#SM_CXEDGE)*2
        Size\cy = Max(Size\cy+GetSystemMetrics_(#SM_CXEDGE)*2, 20)
       
      Case #PB_GadgetType_ComboBox
        GetTextExtentPoint32_(DC, @"Hg", 2, @Size.SIZE)
        Size\cy = Max(Size\cy + 8, 21)
        Size\cx = Size\cy 
       
      Case #PB_GadgetType_Image
        Size\cx = GadgetWidth(Gadget)
        Size\cy = GadgetHeight(Gadget)
      
      Case #PB_GadgetType_Frame3D
        Text$ = GetGadgetText(Gadget)
        GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
        Size\cx + GetSystemMetrics_(#SM_CXEDGE)*2
        Size\cy = Max(Size\cy+GetSystemMetrics_(#SM_CYEDGE)*2, 24)
        Size\cx + 10
    EndSelect
   
    SelectObject_(DC, oldFont)
    ReleaseDC_(GadgetID(Gadget), DC)
    *Width\w  = Size\cx
    *Height\w = Size\cy
 
  CompilerCase #PB_OS_Linux
 
    Protected *Gadget.PB_Gadget = IsGadget(Gadget)
    Protected RealSize.GtkRequisition
    Protected Size.GtkRequisition
   
    If *Gadget And *Gadget\Container And GadgetType(Gadget) <> #PB_GadgetType_ComboBox
      gtk_widget_size_request_(*Gadget\Container, @RealSize)
      gtk_widget_set_size_request_(*Gadget\Container, -1, -1)
      gtk_widget_size_request_(*Gadget\Container, @Size)     
      gtk_widget_set_size_request_(*Gadget\Container, RealSize\Width, RealSize\Height)
    Else
      gtk_widget_size_request_(GadgetID(Gadget), @RealSize)
      gtk_widget_set_size_request_(GadgetID(Gadget), -1, -1)             
      gtk_widget_size_request_(GadgetID(Gadget), @Size)   
      gtk_widget_set_size_request_(GadgetID(Gadget), RealSize\Width, RealSize\Height)
    EndIf
   
    If GadgetType(Gadget) = #PB_GadgetType_ComboBox Or GadgetType(Gadget) = #PB_GadgetType_String
      *Width\w  = 20
    Else
      *Width\w  = Size\Width
    EndIf

    *Height\w = Size\Height   
  CompilerCase #PB_OS_MacOS
 
    Type = GadgetType(Gadget)
   
    If Type = #PB_GadgetType_Image   
      *Width\w = GadgetWidth(Gadget)
      *Height\w = GadgetHeight(Gadget)
     
    ElseIf Type = #PB_GadgetType_Text
      realwidth   = GadgetWidth(Gadget)
     
      *Width\w = 40
      *Height\w = 20     
     
      ResizeGadget(Gadget, #PB_Ignore, #PB_Ignore, 1000, #PB_Ignore)
     
      If GetBestControlRect_(GadgetID(Gadget), @Rect.OSX_Rect, @BaseLine.w) = #noErr
        Height = Rect\bottom - Rect\top
        If Height > 0
       
          Min = 0
          Max = 1000
         
          While Max > Min+2
            Mid = (Min + Max) / 2
           
            ResizeGadget(Gadget, #PB_Ignore, #PB_Ignore, Mid, #PB_Ignore)
           
            If GetBestControlRect_(GadgetID(Gadget), @Rect.OSX_Rect, @BaseLine.w) <> #noErr
              ProcedureReturn
            EndIf
           
            If Rect\bottom - Rect\top > Height
              Min = Mid
            Else
              Max = Mid
            EndIf
          Wend
         
          *Width\w = Rect\right - Rect\left + 2
          *Height\w = Max(Height, 20)
        EndIf
         
      EndIf
     
      ResizeGadget(Gadget, #PB_Ignore, #PB_Ignore, realwidth, #PB_Ignore)

    Else
      If GetBestControlRect_(GadgetID(Gadget), @Rect.OSX_Rect, @BaseLine.w) = #noErr
        *Width\w = Rect\right - Rect\left
        *Height\w = Max(Rect\bottom - Rect\top, 20)
       
        If Type = #PB_GadgetType_Button Or Type = #PB_GadgetType_String
          *Height\w = Max(*Height\w, 24)       
        EndIf       
      Else
        *Width\w = 40
        *Height\w = 20
      EndIf
     
      If Type = #PB_GadgetType_String Or Type  = #PB_GadgetType_ComboBox       
        *Width\w = 30
      EndIf
   
    EndIf
 
  CompilerEndSelect
 
EndProcedure

; convinience wrappers if only one size is needed
;
Procedure.w GetRequiredWidth(Gadget, Flags = 0)
  Protected Width.w, Height.w
  GetRequiredSize(Gadget, @Width, @Height, Flags)
  ProcedureReturn Width
EndProcedure

Procedure.w GetRequiredHeight(Gadget, Flags = 0)
  Protected Width.w, Height.w
  GetRequiredSize(Gadget, @Width, @Height, Flags)
  ProcedureReturn Height
EndProcedure 
;}

Enumeration
  #Sizing_MinimumSize
  #Sizing_Stretch
  #Sizing_Centre
  #Sizing_Fixed
  #Sizing_FixedMinimumSize
EndEnumeration

Enumeration 
  #GeneralType_Window
  #GeneralType_Container
  #GeneralType_Gadget
EndEnumeration

Enumeration
  #Orientation_Horizontal
  #Orientation_Vertical
EndEnumeration

Enumeration 1000
  #PB_GadgetType_Window
  #PB_GadgetType_HBox
  #PB_GadgetType_VBox
  #PB_GadgetType_Spacer
;  #PB_GadgetType_
;  #PB_GadgetType_
;  #PB_GadgetType_
;  #PB_GadgetType_
;  #PB_GadgetType_
EndEnumeration

Structure GadgetLayout
  ID.i
  ParentID.i
  WindowID.i

  Type.w
  GeneralType.b
  Name.s

  MinWidth.w
  MinHeight.w
  
  DesiredWidth.w
  DesiredHeight.w

  FlexWidthType.b
  FlexHeightType.b

  ActualX.w
  ActualY.w
  ActualWidth.w
  ActualHeight.w

  ItemID.i
  Orientation.b
EndStructure

Global NewList gl.GadgetLayout()

Procedure CalculateMinimumSizes(Orientation.b, ParentID.i, *AreaWidth.Word, *AreaHeight.Word, BorderTop.b = 0, BorderBottom.b = 0, BorderLeft.b = 0, BorderRight.b = 0, Spacing.b = 6)
  ResetList(gl())

  Protected newWidth.w = 0
  Protected newHeight.w = 0
  
  ForEach gl()
    If gl()\ParentID = ParentID
      If gl()\GeneralType <> #GeneralType_Gadget
        Protected ContainerWidth.w = gl()\MinWidth
        Protected ContainerHeight.w = gl()\MinHeight

        Protected *CurrentGadget.i = @gl()
        If gl()\Type = #PB_GadgetType_Frame3D
          CalculateMinimumSizes(gl()\Orientation, gl()\ID, @ContainerWidth, @ContainerHeight, 20, 6, 6, 6)
        Else
          CalculateMinimumSizes(gl()\Orientation, gl()\ID, @ContainerWidth, @ContainerHeight, 0, 4, 0, 4)
        EndIf
        ChangeCurrentElement(gl(), *CurrentGadget)

        gl()\MinWidth = ContainerWidth
        gl()\MinHeight = ContainerHeight
      EndIf

      If Orientation = #Orientation_Horizontal
        newWidth = newWidth + gl()\MinWidth + Spacing
        If newHeight < gl()\MinHeight
          newHeight = gl()\MinHeight
        EndIf
      Else
        newHeight = newHeight + gl()\MinHeight + Spacing
        If newWidth < gl()\MinWidth
          newWidth = gl()\MinWidth
        EndIf
      EndIf
    EndIf
  Next

  ; remove the extra space at the end
  If Orientation = #Orientation_Horizontal
    newWidth = newWidth - Spacing
  Else
    newHeight = newHeight - Spacing
  EndIf

  newWidth = newWidth + BorderLeft + BorderRight
  newHeight = newHeight + BorderTop + BorderBottom
  
  If *AreaWidth\w < newWidth
    *AreaWidth\w = newWidth
  EndIf
  If *AreaHeight\w < newHeight
    *AreaHeight\w = newHeight
  EndIf
EndProcedure

Procedure OrientGadgets(Orientation.b, ParentID.i, MinimumWidth.w, MinimumHeight.w, *AreaWidth.Word, *AreaHeight.Word, BorderTop.b = 0, BorderBottom.b = 0, BorderLeft.b = 0, BorderRight.b = 0, Spacing.b = 6)
  Protected TotalMinHeight.w = MinimumHeight ;+ BorderTop + BorderBottom
  Protected TotalMinWidth.w = MinimumWidth ;+ BorderLeft + BorderRight

  If *AreaWidth\w < TotalMinWidth
    *AreaWidth\w = TotalMinWidth
  EndIf
  If *AreaHeight\w < TotalMinHeight
    *AreaHeight\w = TotalMinHeight
  EndIf

;-------------------------------------------------

  Protected RemainingAreaWidth.w = *AreaWidth\w - TotalMinWidth
  Protected RemainingAreaHeight.w = *AreaHeight\w - TotalMinHeight
  Protected InnerHeight.w = *AreaHeight\w - BorderTop - BorderBottom
  Protected InnerWidth.w = *AreaWidth\w - BorderLeft - BorderRight

;-------------------------------------------------

  Protected WidthFlexCount.w = 0
  Protected HeightFlexCount.w = 0
  Protected GadgetCount.w = 0

  ForEach gl()
    If gl()\ParentID = ParentID
      GadgetCount + 1
      
      Select gl()\FlexWidthType
        Case #Sizing_Stretch, #Sizing_Centre
          WidthFlexCount = WidthFlexCount + 1
      EndSelect
    
      Select gl()\FlexHeightType
        Case #Sizing_Stretch, #Sizing_Centre
          HeightFlexCount = HeightFlexCount + 1
      EndSelect
    EndIf
  Next

  Protected RemainingWidth.w, RemainingHeight.w
  If Orientation = #Orientation_Horizontal
    If WidthFlexCount = 0
      RemainingWidth = RemainingAreaWidth
    Else
      RemainingWidth = Int(RemainingAreaWidth / WidthFlexCount)
    EndIf
    
    RemainingHeight = InnerHeight
  Else
    If HeightFlexCount = 0
      RemainingHeight = RemainingAreaHeight
    Else
      RemainingHeight = Int(RemainingAreaHeight / HeightFlexCount)
    EndIf
    
    RemainingWidth = InnerWidth
  EndIf

;-------------------------------------------------

  Protected MaxHeight.w = 0 + BorderTop
  Protected MaxWidth.w = 0 + BorderLeft
  
  Protected ActualX.w = MaxWidth
  Protected ActualY.w = MaxHeight
  Protected t.i = 0

  ForEach gl()
    If gl()\ParentID = ParentID
      gl()\ActualX = ActualX
      gl()\ActualY = ActualY
      
      Select gl()\FlexWidthType
        Case #Sizing_Stretch
          If Orientation = #Orientation_Horizontal
            If RemainingWidth > 0
              gl()\ActualWidth = gl()\MinWidth + RemainingWidth
            Else
              gl()\ActualWidth = gl()\MinWidth
            EndIf
          Else
            If gl()\MinWidth < InnerWidth
              gl()\ActualWidth = InnerWidth
            Else
              gl()\ActualWidth = gl()\MinWidth
            EndIf
          EndIf
        Default
          gl()\ActualWidth = gl()\MinWidth
      EndSelect

      Select gl()\FlexHeightType
        Case #Sizing_Stretch, #Sizing_FixedMinimumSize
          If Orientation = #Orientation_Vertical
            If RemainingHeight > 0
              gl()\ActualHeight = gl()\MinHeight + RemainingHeight
            Else
              gl()\ActualHeight = gl()\MinHeight
            EndIf
          Else
            If gl()\MinHeight < InnerHeight
              gl()\ActualHeight = InnerHeight
            Else
              gl()\ActualHeight = gl()\MinHeight
            EndIf
          EndIf
        Default
          gl()\ActualHeight = gl()\MinHeight
      EndSelect

      If gl()\GeneralType = #GeneralType_Container
        Protected ContainerWidth.w = gl()\ActualWidth
        Protected ContainerHeight.w = gl()\ActualHeight

        Protected *CurrentGadget.i = @gl()
        If gl()\Type = #PB_GadgetType_Frame3D
          OrientGadgets(gl()\Orientation, gl()\ID, gl()\MinWidth, gl()\MinHeight, @ContainerWidth, @ContainerHeight, 20, 6, 6, 6)
        Else
          OrientGadgets(gl()\Orientation, gl()\ID, gl()\MinWidth, gl()\MinHeight, @ContainerWidth, @ContainerHeight, 0, 4, 0, 4)
        EndIf
        ChangeCurrentElement(gl(), *CurrentGadget)

        gl()\ActualWidth = ContainerWidth
        gl()\ActualHeight = ContainerHeight
      EndIf

      Select gl()\FlexWidthType
        Case #Sizing_Centre
          If Orientation = #Orientation_Horizontal
            t = Int(((gl()\ActualWidth + RemainingWidth) / 2) - (gl()\ActualWidth / 2))
            gl()\ActualX = gl()\ActualX + t
          Else
            t = Int((InnerWidth / 2) - (gl()\ActualWidth / 2))
            gl()\ActualX = gl()\ActualX + t
          EndIf
      EndSelect

      Select gl()\FlexHeightType
        Case #Sizing_Centre
          If Orientation = #Orientation_Horizontal
            t = Int((InnerHeight / 2) - (gl()\ActualHeight / 2))
            gl()\ActualY = gl()\ActualY + t
          Else
            t = Int(((gl()\ActualHeight + RemainingHeight) / 2) - (gl()\ActualHeight / 2))
            gl()\ActualY = gl()\ActualY + t
          EndIf
      EndSelect

      If gl()\Type <> #PB_GadgetType_Spacer
        ResizeGadget(gl()\ID, gl()\ActualX, gl()\ActualY, gl()\ActualWidth, gl()\ActualHeight)
      EndIf

      If Orientation = #Orientation_Horizontal
        MaxWidth = MaxWidth + Spacing + gl()\ActualWidth
        If MaxHeight < gl()\ActualHeight
          MaxHeight = gl()\ActualHeight
        EndIf
        If gl()\FlexWidthType = #Sizing_Centre
           MaxWidth = MaxWidth + RemainingWidth ; - gl()\ActualWidth - Spacing - BorderLeft + BorderRight
        EndIf
        ActualX = MaxWidth
      Else
        MaxHeight = MaxHeight + Spacing + gl()\ActualHeight
        If MaxWidth < gl()\ActualWidth
          MaxWidth = gl()\ActualWidth
        EndIf
        If gl()\FlexHeightType = #Sizing_Centre
          MaxHeight = MaxHeight + RemainingHeight
        EndIf
        ActualY = MaxHeight
      EndIf

    EndIf
  Next
  
  If Orientation = #Orientation_Horizontal
    MaxWidth = MaxWidth - Spacing
  Else
    MaxHeight = MaxHeight - Spacing
  EndIf

  If *AreaWidth\w < MaxWidth + BorderRight
    *AreaWidth\w = MaxWidth + BorderRight
  EndIf
  If *AreaHeight\w < MaxHeight + BorderBottom
    *AreaHeight\w = MaxHeight + BorderBottom
  EndIf
EndProcedure

Procedure.i AddGadget(pName.s, pParentID.i, pWindowID.i, pGadgetType.i, pText.s, pDesiredWidth.i, pDesiredHeight.i, pFlexWidthType.b, pFlexHeightType.b, pFlags.i = 0, pPath.s = "")
  If pDesiredWidth = #PB_Any
    pDesiredWidth = 0
  EndIf
  If pDesiredHeight = #PB_Any
    pDesiredHeight = 0
  EndIf

  AddElement(gl())
  gl()\ID = ListSize(gl())
  gl()\Type = pGadgetType
    
  gl()\ParentID = pParentID
  gl()\WindowID = pWindowID
  Select pGadgetType
  Case #PB_GadgetType_Window
    gl()\GeneralType = #GeneralType_Window
  Case #PB_GadgetType_HBox, #PB_GadgetType_VBox, #PB_GadgetType_Frame3D
    gl()\GeneralType = #GeneralType_Container
  Default
    gl()\GeneralType = #GeneralType_Gadget
  EndSelect
  
  gl()\FlexWidthType = pFlexWidthType
  gl()\FlexHeightType = pFlexHeightType 
  
  gl()\Name = pName
  
  If gl()\Type = #PB_GadgetType_HBox
    gl()\Orientation = #Orientation_Horizontal
  Else
    gl()\Orientation = #Orientation_Vertical
  EndIf
  
  If gl()\Type = #PB_GadgetType_Window
    OpenWindow(gl()\ID, 0, 0, pDesiredWidth, pDesiredHeight, pText,  pFlags)
    gl()\GeneralType = #GeneralType_Window
    gl()\WindowID = gl()\ID
  Else
    If pParentID <> pWindowID
      OpenGadgetList(pParentID)
    EndIf
    
    Protected HasMinimumSize.b = #True
  
    Select gl()\Type
    Case #PB_GadgetType_Button
      ButtonGadget(gl()\ID, 0, 0, 0, 0, pText)
    Case #PB_GadgetType_CheckBox
      CheckBoxGadget(gl()\ID, 0, 0, 0, 0, pText)
    Case #PB_GadgetType_ComboBox
      ComboBoxGadget(gl()\ID, 0, 0, 0, 0)
    Case #PB_GadgetType_Image
      gl()\ItemID = LoadImage(#PB_Any, pPath)
      ImageGadget(gl()\ID, 0, 0, 0, 0, ImageID(gl()\ItemID))
    Case #PB_GadgetType_Option
      OptionGadget(gl()\ID, 0, 0, 0, 0, pText)
    Case #PB_GadgetType_String
      StringGadget(gl()\ID, 0, 0, 0, 0, pText)
    Case #PB_GadgetType_Text
      TextGadget(gl()\ID, 0, 0, 0, 0, pText)
    Case #PB_GadgetType_Frame3D
      Frame3DGadget(gl()\ID, 0, 0, 20, 20, pText)
  
    ; specials
    Case #PB_GadgetType_HBox, #PB_GadgetType_VBox
      ContainerGadget(gl()\ID, 0, 0, 20, 20) ; , #PB_Container_Single
    CloseGadgetList()
    Case #PB_GadgetType_Spacer
      HasMinimumSize = #False
    EndSelect
  
    If HasMinimumSize = #True
      GetRequiredSize(gl()\ID, @gl()\MinWidth, @gl()\MinHeight)

      If pDesiredWidth > gl()\MinWidth
        gl()\MinWidth = pDesiredWidth
      EndIf
      
      If pDesiredHeight > gl()\MinHeight
        gl()\MinHeight = pDesiredHeight
      EndIf
    Else
      gl()\MinWidth = 0
      gl()\MinHeight = 0
    EndIf
  EndIf
  
  ProcedureReturn gl()\ID
EndProcedure


Procedure RenderGadgets(pCalculateMinimumSize.b)
  ForEach gl()
    If gl()\Type = #PB_GadgetType_Window
      Protected WinWidth.i = WindowWidth(gl()\ID)
      Protected WinHeight.i = WindowHeight(gl()\ID)
      Protected minWidth.i, minHeight.i
      
      Protected *tmpGadget.i = @gl()
      CalculateMinimumSizes(#Orientation_Vertical, gl()\ID, @minWidth, @minHeight, 8, 8, 8, 8)
      ChangeCurrentElement(gl(), *tmpGadget)
      gl()\MinWidth = minWidth
      gl()\MinHeight = minHeight
  
      Protected ResizeToMin.b = #False
      If WinWidth < minWidth : WinWidth = minWidth : ResizeToMin = #True : EndIf
      If WinHeight < minHeight : WinHeight = minHeight : ResizeToMin = #True : EndIf
  
      If ResizeToMin = #True
        ResizeWindow(gl()\ID, #PB_Ignore, #PB_Ignore, WinWidth, WinHeight)
      EndIf
      
      OrientGadgets(#Orientation_Vertical, gl()\ID, minWidth, minHeight, @WinWidth, @WinHeight, 8, 8, 8, 8)
      ChangeCurrentElement(gl(), *tmpGadget)
    EndIf
  Next
EndProcedure

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
Procedure WndProc(hwnd, uMsg, wParam, lParam)
  Protected result = #PB_ProcessPureBasicEvents
  
  If uMsg = #WM_EXITSIZEMOVE
    RenderGadgets(#False)
  EndIf
  
  ProcedureReturn result
EndProcedure
CompilerEndIf

Declare GadgetEventSelection(pWindowEvent, pGadgetEvent, pTypeEvent)
Declare MenuEventSelection(pWindowEvent, pMenuEvent)

Procedure EventLoop()
  RenderGadgets(#False)
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  ForEach gl()
    If gl()\Type = #PB_GadgetType_Window
      SetWindowCallback(@WndProc(), gl()\ID)
    EndIf
  Next
  CompilerEndIf
  
  Repeat
    Protected Event  = WaitWindowEvent()
    Protected Window = EventWindow()
  
    Select Event
    Case #PB_Event_Gadget
      Protected Gadget = EventGadget()
      Protected Type   = EventType()
      GadgetEventSelection(Window, Gadget, Type)
    Case #PB_Event_Menu
      Protected Menu = EventMenu()
      MenuEventSelection(Window, Menu)
  CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
    Case #PB_Event_SizeWindow
      RenderGadgets(#False)
  CompilerEndIf
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Case #PB_Event_MaximizeWindow, #PB_Event_RestoreWindow
      RenderGadgets(#False)
  CompilerEndIf
  
  
    Case #PB_Event_CloseWindow
      Define Quit = 1
    EndSelect
    
  Until Quit = 1
EndProcedure

Procedure GetGadgetID(pWindowName.s, pGadgetName.s)
  Protected WinID.i
  
  ForEach gl()
    If gl()\ParentID = -1 And gl()\Name = pWindowName
      WinID = gl()\ID
      Break
    EndIf
  Next
  
  ForEach gl()
    If gl()\WindowID = WinID And gl()\Name = pGadgetName
      Break
    EndIf
  Next
  
  ProcedureReturn gl()\ID
EndProcedure

; IDE Options = PureBasic 4.60 Beta 3 (Windows - x86)
; CursorPosition = 740
; FirstLine = 452
; Folding = l7-
; EnableXP